﻿using System;
using System.Collections.Generic;
using System.Linq;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;

namespace YArchitech.Revit
{
	public class RevitAPIUIOperate
	{
		public static List<Element> SelectionCheck(Autodesk.Revit.DB.Document doc, Selection sel, SelectionTypePara selectionTypePara, bool beConnFixtures)
		{
			new List<Element>();
			List<Element> list = new List<Element>();
			List<Element> list2 = new List<Element>();
			new List<Element>();
			if (sel.GetElementIds().Any<ElementId>())
			{
				foreach (ElementId elementId in sel.GetElementIds())
				{
					list.Add(doc.GetElementById(elementId));
				}
			}
			bool flag = true;
			bool flag2 = true;
			foreach (Element element in list)
			{
				if (selectionTypePara.PipingCategory == element.Category.Id.IntegerValue)
				{
					list2.Add(element);
					flag = false;
				}
				else if (selectionTypePara.EquipmentCategory == element.Category.Id.IntegerValue)
				{
					list2.Add(element);
					flag2 = false;
				}
			}
			RevitVersionFuncs.ClearSelection(sel);
			if (flag && flag2)
			{
				PickedBox pickedBox = sel.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)0, selectionTypePara.PipingAndEquipmentTip);
				using (List<Element>.Enumerator enumerator2 = RevitAPIUIOperate.GetAllElement(doc, pickedBox, beConnFixtures).GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						Element element2 = enumerator2.Current;
						if (element2 is Pipe)
						{
							if (!YJKRevitTools.isRiserPiping(element2))
							{
								list2.Add(element2);
							}
						}
						else if (element2 is FamilyInstance)
						{
							FamilyInstance familyInstance = element2 as FamilyInstance;
							int integerValue = element2.Category.Id.IntegerValue;
							if (integerValue == -2001160 && familyInstance.MEPModel.ConnectorManager != null)
							{
								list2.Add(element2);
							}
							if (integerValue == -2008055 && (familyInstance.Symbol.Family.Name.Contains("地漏") || familyInstance.Symbol.Family.Name.Contains("清扫口")))
							{
								list2.Add(element2);
							}
						}
					}
					return list2;
				}
			}
			if (flag)
			{
				PickedBox pickedBox = sel.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)0, selectionTypePara.PipingTip);
				using (List<Element>.Enumerator enumerator2 = RevitAPIUIOperate.GetAllElement(doc, pickedBox, beConnFixtures).GetEnumerator())
				{
					while (enumerator2.MoveNext())
					{
						Element element3 = enumerator2.Current;
						if (element3 is Pipe)
						{
							list2.Add(element3);
						}
					}
					return list2;
				}
			}
			if (flag2)
			{
				PickedBox pickedBox = sel.PickBox((Autodesk.Revit.UI.Selection.PickBoxStyle)0, selectionTypePara.EquipmentTip);
				foreach (Element element4 in RevitAPIUIOperate.GetAllElement(doc, pickedBox, beConnFixtures))
				{
					if (element4 is FamilyInstance)
					{
						FamilyInstance familyInstance2 = element4 as FamilyInstance;
						int integerValue2 = element4.Category.Id.IntegerValue;
						if (integerValue2 == -2001160)
						{
							list2.Add(element4);
						}
						if (integerValue2 == -2008055 && (familyInstance2.Symbol.Family.Name.Contains("地漏") || familyInstance2.Symbol.Family.Name.Contains("清扫口")))
						{
							list2.Add(element4);
						}
					}
				}
			}
			return list2;
		}

		public static List<Element> GetAllElement(Autodesk.Revit.DB.Document doc, PickedBox pickedBox, bool beConnFixtures = false)
		{
			List<Element> list = new List<Element>();
			if (pickedBox == null)
			{
				return list;
			}
			IEnumerable<Document> linkDocuments = doc.GetLinkDocuments();
			double[] viewRange = RevitAPIUIOperate.GetViewRange2(doc.ActiveView, beConnFixtures);
			if (viewRange == null)
			{
				YJKMessageBox.Information("操作视图必须为平面视图！");
				return null;
			}
			BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(RevitAPIUIOperate.CreatOutLine(viewRange, pickedBox.Max, pickedBox.Min));
			list = RevitAPIUIOperate.GetElementFormDoc(doc, filter, true);
			if (linkDocuments == null)
			{
				return list;
			}
			foreach (Autodesk.Revit.DB.Document document in linkDocuments)
			{
				if (document != null)
				{
					List<Element> elementFormDoc = RevitAPIUIOperate.GetElementFormDoc(document, filter, false);
					list.AddRange(elementFormDoc);
				}
			}
			return list;
		}

		private static List<Element> GetElementFormDoc(Autodesk.Revit.DB.Document doc, BoundingBoxIntersectsFilter filter, bool isHavePipe)
		{
			List<Element> list = new List<Element>();
			List<Element> list2 = new List<Element>();
			list2 = new FilteredElementCollector(doc).WherePasses(filter).ToElements().ToList<Element>();
			if (isHavePipe)
			{
				return list2;
			}
			list.AddRange(list2);
			foreach (Element element in list2)
			{
				if (element is Pipe)
				{
					list.Remove(element);
				}
			}
			return list;
		}

		public static Outline CreatOutLine(double[] viewRanges, XYZ point1, XYZ point2)
		{
			XYZ[] array = RevitAPIUIOperate.ReCombinPoints(point1, point2);
			XYZ xyz = new XYZ(array[0].X, array[0].Y, viewRanges[0]);
			XYZ xyz2 = new XYZ(array[1].X, array[1].Y, viewRanges[1]);
			return new Outline(xyz, xyz2);
		}

		private static XYZ[] ReCombinPoints(XYZ point1, XYZ point2)
		{
			XYZ[] array = new XYZ[2];
			double x;
			double x2;
			if (point1.X > point2.X)
			{
				x = point2.X;
				x2 = point1.X;
			}
			else
			{
				x2 = point2.X;
				x = point1.X;
			}
			double y;
			double y2;
			if (point1.Y > point2.Y)
			{
				y = point2.Y;
				y2 = point1.Y;
			}
			else
			{
				y2 = point2.Y;
				y = point1.Y;
			}
			array[0] = new XYZ(x, y, 0.0);
			array[1] = new XYZ(x2, y2, 0.0);
			return array;
		}

		public static double[] GetViewRange2(Autodesk.Revit.DB.View view, bool beConnFixtures = false)
		{
			if (!(view is ViewPlan))
			{
				return null;
			}
			Document document = view.Document;
			double[] array = new double[2];
			if (view.GenLevel.GetParameter("立面") != null)
			{
				Parameter parameter = view.GenLevel.GetParameter("立面");
				array[0] = parameter.AsDouble();
			}
			IEnumerable<Element> enumerable = new HYSystemElementFilter(document).GetElementsByBICategory(BuiltInCategory.OST_Levels).ToList<Element>();
			SortedSet<double> sortedSet = new SortedSet<double>();
			foreach (Element element in enumerable)
			{
				if (element is Level && element.GetParameter("立面") != null)
				{
					Parameter parameter2 = element.GetParameter("立面");
					sortedSet.Add(parameter2.AsDouble());
				}
			}
			bool flag = false;
			foreach (double num in sortedSet)
			{
				if (flag)
				{
					array[1] = num - 0.016404199475065617;
					break;
				}
				if (num == array[0])
				{
					flag = true;
				}
			}
			if (array[1] <= array[0])
			{
				array[1] = array[0] + 9.84251968503937;
			}
			if (beConnFixtures)
			{
				array[0] = array[0] - 4.9212598425196852;
			}
			return array;
		}

		private static double[] GetViewRange(Autodesk.Revit.DB.View view)
		{
			if (!(view is ViewPlan))
			{
				return null;
			}
			Document document = view.Document;
			double[] array = new double[2];
			PlanViewRange viewRange = (view as ViewPlan).GetViewRange();
			ElementId levelId = viewRange.GetLevelId(0);
			double num = 30.0;
			ElementId levelId2 = viewRange.GetLevelId(1);
			if (levelId2 != null && document.GetElementById(levelId) != null && document.GetElementById(levelId2) is Level)
			{
				num = (document.GetElementById(levelId2) as Level).Elevation + viewRange.GetOffset(1);
			}
			double elevation = (document.GetElementById(levelId) as Level).Elevation;
			array[1] = elevation + num;
			ElementId levelId3 = viewRange.GetLevelId(2);
			if (levelId3.IntegerValue <= 0)
			{
				array[0] = elevation;
			}
			else
			{
				double offset = viewRange.GetOffset(2);
				double elevation2 = (document.GetElementById(levelId3) as Level).Elevation;
				array[0] = elevation2 + offset;
			}
			return array;
		}

		public static List<Element> SelectionCheck(Selection sel, SelectionTypePara selectionTypePara, Autodesk.Revit.DB.Document doc)
		{
			new List<Element>();
			List<Element> list = new List<Element>();
			List<Element> list2 = new List<Element>();
			if (sel.GetElementIds().Any<ElementId>())
			{
				foreach (ElementId elementId in sel.GetElementIds())
				{
					list.Add(doc.GetElementById(elementId));
				}
			}
			bool flag = true;
			bool flag2 = true;
			foreach (Element element in list)
			{
				if (selectionTypePara.PipingCategory == element.Category.Id.IntegerValue)
				{
					list2.Add(element);
					flag = false;
				}
				else if (selectionTypePara.EquipmentCategory == element.Category.Id.IntegerValue)
				{
					list2.Add(element);
					flag2 = false;
				}
			}
			RevitVersionFuncs.ClearSelection(sel);
			if (flag && flag2)
			{
				IEnumerator<Reference> enumerator3 = sel.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, selectionTypePara.PipingAndEquipmentFilter, selectionTypePara.PipingAndEquipmentTip).GetEnumerator();
				{
					while (enumerator3.MoveNext())
					{
						Reference reference = enumerator3.Current;
						Element element2 = doc.GetElement(reference);
						list2.Add(element2);
					}
					return list2;
				}
			}
			if (flag)
			{
				IEnumerator<Reference> enumerator3 = sel.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, selectionTypePara.PipingFilter, selectionTypePara.PipingTip).GetEnumerator();
				{
					while (enumerator3.MoveNext())
					{
						Reference reference2 = enumerator3.Current;
						Element element3 = doc.GetElement(reference2);
						list2.Add(element3);
					}
					return list2;
				}
			}
			if (flag2)
			{
				foreach (Reference reference3 in sel.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, selectionTypePara.EquipmentFilter, selectionTypePara.EquipmentTip))
				{
					Element element4 = doc.GetElement(reference3);
					list2.Add(element4);
				}
			}
			return list2;
		}
	}
}
